use serde::{Serialize};
use std::collections::HashMap;
use serde_json::Value;

#[derive(Serialize, Debug)]
pub struct Query {
    pub db: String,
    pub table: Option<String>,
    pub start: Option<String>,
    pub stop: Option<String>,
    pub tags: Option<Vec<HashMap<String, String>>>,
    pub field: Option<String>,
    pub func: Option<Vec<String>>
}

impl Query {
    pub fn tables(db: String) -> anyhow::Result<String> {
        Self::base(db, None)
    }
    pub fn tags(db: String, table: String) -> anyhow::Result<String> {
        Self::base(db, Some(table))
    }
}
impl Query {
    fn base(db: String, table: Option<String>) -> anyhow::Result<String> {
        let o = Self {
            db, table,
            start: Some(String::from("1970-01-01T00:00:00.000000Z")),
            stop: None,
            tags: None,
            field: None,
            func: Some(vec![String::from("first")])
        };
        
        Ok(serde_json::to_string(&o)?)
    }
}

#[derive(Serialize, Debug)]
pub struct Table {
    pub name: String,
    #[serde(rename = "tagNames")]
    pub tag_names: Option<Vec<String>>,
    pub tags: Option<Vec<Tag>>
}

#[derive(Serialize, Debug)]
pub struct Tag {
    pub name: String,
    pub fields: Vec<Field>
}

#[derive(Serialize, Debug)]
pub struct Field {
    pub name: String,
    pub value: Option<Value>,
    #[serde(rename = "type")]
    pub v_type: Option<String>,
    pub timespan: Option<u64>
}